package com.example.demo.hutool.redis;

import com.alibaba.fastjson.JSON;
import redis.clients.jedis.*;
import redis.clients.jedis.params.SetParams;

import java.math.BigDecimal;
import java.util.*;

public class RedisTypeTest {

    public static Jedis jedis = null;

    static {
        JedisPool jedisPool = getJedisPool();
        jedis = jedisPool.getResource();
    }

    public static JedisPool getJedisPool() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 最大连接数
        jedisPoolConfig.setMaxTotal(10);
        // 最大连接阻塞等待时间
        jedisPoolConfig.setMaxWaitMillis(-1);
        // 最大空闲连接数
        jedisPoolConfig.setMaxIdle(0);
        // 最小空闲连接数
        jedisPoolConfig.setMinIdle(0);
        jedisPoolConfig.setTestOnBorrow(true);
        jedisPoolConfig.setTestOnReturn(true);
        int to = 500000;
        JedisPool jPool = new JedisPool(jedisPoolConfig, "172.20.54.213", 6379, to, "123456");

        return jPool;
    }

    public static int getHash(String str) {
        final int p = 16777619;
        int hash = (int) 2166136261L;
        for (int i = 0; i < str.length(); i++)
            hash = (hash ^ str.charAt(i)) * p;
        hash += hash << 13;
        hash ^= hash >> 7;
        hash += hash << 3;
        hash ^= hash >> 17;
        hash += hash << 5;

        // 如果算出来的值为负数则取其绝对值
        if (hash < 0) {
            hash = Math.abs(hash);
        }
        return hash;
    }

    static final int hash(String key) {
        long index = Math.abs((long) (key.hashCode() % 1999999999));
        int length = key.length();
        if (index - length > 1) {
            // index = index - length;
        }
        return (int) index;
    }

    public static void main(String[] args) {

//        Pipeline pipelined = jedis.pipelined();
//        //增量map
//        Map<String, Map<String, Object>> tableStatus = new HashMap<>();
//
//
//        int index = 0;
//
//        String groupname = "group-dscggg1";
//
//        String consumer = "dscg-quegry1";
//        ArrayList<String> limit = new ArrayList<>();
//        limit.add("sxmstream1");
//        limit.add("sxmstream2");
//
//        for (String key : limit) {
//            if (!tableStatus.containsKey(key)) {
//                try {
//                    jedis.xgroupCreate(key, key + groupname, null, true);
//                    HashMap<String, Object> groupnameMap = new HashMap<>();
//                    groupnameMap.put(consumer, key + groupname);
//                    tableStatus.put(key, groupnameMap);
//                } catch (Exception e) {
//                }
//            }
//        }
//
//
//        for (String key : limit) {
//            Map<String, StreamEntryID> map = new HashMap<>();
//            map.put(key, null);
//            Map.Entry<String, StreamEntryID> video = map.entrySet().stream().findFirst().get();
//            pipelined.xreadGroup(tableStatus.get(key).get(consumer).toString(), consumer, 10000, 0, false, video);
//
//        }
//        List<Object> objects = pipelined.syncAndReturnAll();
//        for (Object object : objects) {
//            if (object == null) {
//                continue;
//            }
//            List<Map.Entry<String, List<StreamEntry>>> list = (List<Map.Entry<String, List<StreamEntry>>>) object;
//            if (list != null && list.size() > 0) {
//                Map<Object, Object> map = new HashMap<>();
//                for (Map.Entry<String, List<StreamEntry>> stringListEntry : list) {
//                    String key = stringListEntry.getKey();
//                    List<StreamEntry> value = stringListEntry.getValue();
//                    map.put(key, JSON.toJSONString(value));
//                }
//                System.out.println();
//            }
//        }

        checkDate();


    }


    /**
     * 检查数据
     */
    private static void checkDate() {
        for (int i = 0; i < 1; i++) {
            System.out.println("------------------" + i);
            jedis.select(i);
            Set<String> keys = jedis.keys("*");
            for (String key : keys) {
                String type = jedis.type(key);
                if (type.equals("string")) {
                    System.out.println("key--->" + key + "---value--->" + jedis.get(key));
                }
                if (type.equals("set")) {
                    System.out.println("key--->" + key + "---value--->" + jedis.scard(key));
                }
                if (type.equals("zset")) {
                    System.out.println("key--->" + key + "---value--->" + jedis.zcard(key));
                }
                if (type.equals("list")) {
                    System.out.println("key--->" + key + "---value--->" + jedis.llen(key));
                }
                if (type.equals("hash")) {
                    System.out.println("key--->" + key + "---value--->" + jedis.hlen(key));
                }
            }
        }
    }

    /**
     * 测试String类型
     */
    public void testStringType() {
        // 添加单条数据
        jedis.set("sxm", "1");
        // 获取单条数据
        String name = jedis.get("ml");
        System.out.println("name=" + name);
        // 添加多条数据 key:val key:val
        jedis.mset("addr", "sh", "gender", "男", "age", "25");
        // 获取多条数据
        List<String> mVal = jedis.mget("addr", "gender", "age");
        mVal.forEach(System.out::print);
        // 删除数据
        //   Long delval = jedis.del(name);
        //  System.out.println("delVal=" + delval);
    }

    /**
     * 操作Hash类型
     */
    public void testHash() {
        // 添加数据
        for (int i = 0; i < 100; i++) {
            //  jedis.hset("sxmhash", i+"", i+"");
        }
        Long sxmhash = jedis.hlen("sxmhash");
        System.out.println(sxmhash);
        ScanParams scanParams = new ScanParams();
        Pipeline pipelined = jedis.pipelined();
        pipelined.hlen("key");

        List<Object> objects = pipelined.syncAndReturnAll();
        for (Object object : objects) {
            System.out.println(object);
        }
        pipelined.scard("set");
        objects = pipelined.syncAndReturnAll();
        for (Object object : objects) {
            System.out.println(object);
        }

//        // 获取数据
//        String val = jedis.hget("redisKey", "hashKey");
//        System.out.println("val = " + val);
//        // 添加多条数据
//        Map<String, String> map = new HashMap<>();
//        map.put("age", "25");
//        map.put("gender", "男");
//        jedis.hmset("mKey", map);
//        List<String> list = jedis.hmget("mKey", "age", "gender");
//
//        list.forEach(System.out::print);
//        Map<String, String> mapVal = jedis.hgetAll("mKey");
//        mapVal.entrySet().forEach(item -> System.out.println(item.getKey() + "-" + item.getValue() + " "));
//        // 删除 第一个redisKey   第二个 hashKey  第三个是要删除的数据名,可以是多个 eg:age,name..
//        jedis.hdel("redisKey", "hashKey", "age");
    }

    public void testzset() {
        //从低到高
        Set<Tuple> math = jedis.zrangeByScoreWithScores("math", 1, 10);


        HashMap<String, Double> scoreMap = new HashMap<String, Double>();
        for (int i = 0; i < 90; i++) {
            scoreMap.put("" + i, (double) i);
        }

        jedis.zadd("math", scoreMap);
        //从高到底
        Set<Tuple> math1 = jedis.zrevrangeByScoreWithScores("math", 10, 1);
        System.out.println();

//        // 查看scoreMap的形式
//        System.out.println("查看scoreMap的形式：" + scoreMap.toString());
//        // 0 第0个元素，-1最后一个元素
//        System.out.println("返回math全部元素：" + jedis.zrange("math", 0, -1));
//        System.out.println("查看key有多少个元素：" + jedis.zcard("math"));
//        // 移除 xiaoli 这个元素
//        System.out.println("移除xiaoli 这个元素");
//        jedis.zrem("math", "xiaoli");
//        // -inf 负无穷  inf 正无穷，即从小到大排序
//        System.out.println("按照递增顺序，返回math全部的元素（含成绩）：" + jedis.zrangeByScoreWithScores("math", "-inf", "inf"));
//        System.out.println("统计math集合，成绩在[80,100]之间的元素个数：" + jedis.zcount("math", 80, 100));

    }

    /**
     * 操作list集合
     */
    public void testList() {
        // 添加数据集合 redisKeys ,val val val
//        for (int i = 0; i <10 ; i++) {
//            jedis.lpush("sxmlist", "左添加"+i);// 左添加
//        }
//        for (int i = 0; i <10 ; i++) {
//            jedis.rpush("sxmlist", "右添加"+i);//右添加
//        }

//        // 获取数据集合
//        //左侧消费
//        List<String> redisListL = jedis.lrange("40Pipelinelist", -3010001, -3000001);
//        //右侧消费
//        List<String> s = jedis.lrange("sxmlist", -10, -1);

        for (int i = 0; i < 10; i++) {
            jedis.lpush("ll", i + "");
        }


        System.out.println();
//        redisListL.forEach(System.out::println);
//        // 获取总条数
//        Long len = jedis.llen("redisKeyL");
//        System.out.println("len = " + len);
//        // 删除数据 redisKey  删除条数   删除的值
//        jedis.lrem("redisKeyL", 1, "ls");
//        // 左弹出,只会弹出左边的第一条数据
//        String keyR = jedis.lpop("redisKeyR");
//        System.out.println("keyR = " + keyR);
    }

    /**
     * 操作set集合
     */
    public void testSet() {
        // 添加数据
        jedis.sadd("sxmset", "aaa", "bbb", "ccc", "ddd");


        // 获取数据
        Set<String> setList = jedis.smembers("redisKey");
        setList.forEach(System.out::println);
        // 获取数据条数
        Long len = jedis.scard("redisKey");
        System.out.println("len = " + len);
        // 删除数据 redisKey  要删除的数据值, val val val
        Long srem = jedis.srem("redisKey", "aaa", "ccc");
        System.out.println("srem = " + srem);
    }

    /**
     * key的失效时间
     */
    public void testExpire() {
        // 添加测试数据
        jedis.set("redisKeyS", "timeout");
        jedis.set("redisKeyMS", "timeout");
        // 设置失效时间 单位秒
        jedis.expire("redisKeyS", 50);
        // 设置失效时间  单位 毫秒
        jedis.pexpire("redisKeyMS", 50000);
        // 查看失效时间 单位 秒,-1为不失效,-2为已失效
        Long s = jedis.ttl("redisKeyS");
        System.out.println("m = " + s);

        // 存储数据时 设置有效时间,单位 秒
        jedis.setex("redisKey", 50, "val");
        // 存储数据时 设置有效时间,单位 毫秒
        jedis.psetex("redisKey", 50000, "val");
        // 获取有效时间  单位  毫秒
        Long ms = jedis.pttl("redisKey");
        System.out.println("ms = " + ms);
    }

    /**
     * 操作SetParams对象
     */
    public void testSetParams() {
        SetParams setParams = new SetParams();
        // redis中不存在该数据的时候才能设置成功
        //setParams.nx();
        // 设置失效时间 单位 秒
        //setParams.ex(50);
        // redis存在该数据的时候才能设置成功
        setParams.xx();
        // 设置失效时间 单位 毫秒
        setParams.px(50000);
        jedis.set("redisKey", "val", setParams);
    }

    /**
     * 获取redis当前库中所有的key
     */
    public void testAllKey() {
        // 获取当前数据库中key的数量
        Long size = jedis.dbSize();
        System.out.println("size = " + size);
        // 查询当前库中的所有 key  * -> 所有
        Set<String> keys = jedis.keys("*");
        keys.forEach(System.out::println);
    }

    /**
     * 层及目录
     */
    public void testDir() {
        jedis.set("user:zs:hobby", "pingpong");
        String str = jedis.get("user:zs:hobby");
        System.out.println("str = " + str);
    }


}
